package com.xinchen.all.ui.activity

import android.annotation.SuppressLint
import android.app.Activity
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattService
import android.bluetooth.BluetoothManager
import android.bluetooth.le.BluetoothLeScanner
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.location.LocationManager
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Message
import android.provider.Settings
import android.text.TextUtils
import android.widget.Button
import androidx.activity.result.contract.ActivityResultContract
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.huyuhui.fastble.callback.BleGattCallback
import com.huyuhui.fastble.callback.BleReadCallback
import com.huyuhui.fastble.exception.BleException
import com.maple.base.base.BaseActivity
import com.maple.ble.BleManager
import com.maple.ble.callback.BleConnectCallback
import com.maple.ble.callback.BleScanCallback
import com.maple.ble.data.BleConnectFailType
import com.maple.ble.data.BleScanFailType
import com.maple.ble.device.BleDevice
import com.maple.utils.util.LogUtils
import com.xinchen.all.R
import com.xinchen.all.ui.adapter.BluetoothDeviceAdapter
import com.xinchen.all.ui.adapter.BluetoothDeviceAdapter2
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.launch
import java.util.UUID

class BluetoothActivity : BaseActivity() {
    private var btnBluetooth: Button? = null
    private var btnRead: Button? = null
    private var rvList: RecyclerView? = null

    private var bluetoothAdapter: BluetoothAdapter? = null
    private var bluetoothLeScanner : BluetoothLeScanner? = null

    private val connectCallback: BleConnectCallback.() -> Unit = {
        onConnectStart {
            showToast("开始连接")
        }
        onConnectSuccess { bleDevice, gatt ->
            showToast("连接成功")
//            var serviceUUID: String = ""
//            var readUUID: String = ""
//            gatt?.services?.forEachIndexed { index, bluetoothGattService ->
//                serviceUUID = bluetoothGattService.uuid.toString()
//                bluetoothGattService.characteristics?.forEach { characteristic ->
////                    if(characteristic.properties == BluetoothGattCharacteristic.PROPERTY_READ) {
////                        readUUID = characteristic.uuid.toString()
////                    }
//                    readUUID = characteristic.uuid.toString()
//                    LogUtils.logGGQ("特征properties：${characteristic.properties}")
//                    LogUtils.logGGQ("特征uuid：${characteristic.uuid.toString()}")
//                    BleManager.get().readData(bleDevice,serviceUUID,readUUID) {
//
//                        onReadSuccess { bleDevice, data ->
//                            LogUtils.logGGQ("onReadSuccess 读数据：${data}")
//                        }
//
//                        onReadFail { bleDevice, throwable ->
//                            LogUtils.logGGQ("onReadFail 读数据：${throwable?.message}")
//                        }
//                    }
//                }
//            }
//            if(TextUtils.isEmpty(serviceUUID)) {
//                serviceUUID = "00001101-0000-1000-8000-00805F9B34FB"
//            }
//            if(TextUtils.isEmpty(readUUID)) {
//                readUUID = "Read"
//            }

//            BleManager.get().readData(bleDevice,serviceUUID,readUUID) {
//
//                onReadSuccess { bleDevice, data ->
//                    LogUtils.logGGQ("onReadSuccess 读数据：${data}")
//                }
//
//                onReadFail { bleDevice, throwable ->
//                    LogUtils.logGGQ("onReadFail 读数据：${throwable?.message}")
//                }
//            }


//            BleManager.get().readData(this@BluetoothActivity,bleDevice,bluetoothAdapter!!)

            val uuid: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")

            BleManager.get().readData(bleDevice,uuid.toString(),"read") {
                onReadSuccess { bleDevice, data ->
                    LogUtils.logGGQ("onReadSuccess 读数据：${data}")
                }

                onReadFail { bleDevice, throwable ->
                    LogUtils.logGGQ("onReadFail 读数据：${throwable?.message}")
                }
            }
            btnBluetooth?.text = "已连接：${bleDevice.deviceName}"
        }
        onConnectFail { bleDevice, connectFailType ->
            val msg: String = when (connectFailType) {
                is BleConnectFailType.UnSupportBle -> "设备不支持蓝牙"
                is BleConnectFailType.NoBlePermission -> "权限不足，请检查"
                is BleConnectFailType.NullableBluetoothDevice -> "设备为空"
                is BleConnectFailType.BleDisable -> "蓝牙未打开"
                is BleConnectFailType.ConnectException -> "连接异常(${connectFailType.throwable.message})"
                is BleConnectFailType.ConnectTimeOut -> "连接超时"
                is BleConnectFailType.AlreadyConnecting -> "连接中"
                is BleConnectFailType.ScanNullableBluetoothDevice -> "连接失败，扫描数据为空"
                else -> "连接失败！"
            }
            showToast(msg)
        }

        onDisConnecting { isActiveDisConnected, bleDevice, gatt, status ->
            showToast("正在断开")
        }

        onDisConnected { isActiveDisConnected, bleDevice, gatt, status ->
            showToast("已断开")
            btnBluetooth?.text = "蓝牙"
        }

    }

    private val listAdapter: BluetoothDeviceAdapter by lazy {
        BluetoothDeviceAdapter(this).apply {
            this.setData(arrayListOf())
            this.setListener(object :BluetoothDeviceAdapter.OnClickListener{
                override fun onItemClick(pos: Int, device: BleDevice?) {
                    device?.let {
                        if(!BleManager.get().isConnected(it)) {
                            BleManager.get().connect(it,connectCallback)
                        }
                    }
                }
            })
        }
    }

    private val listAdapter2: BluetoothDeviceAdapter2 by lazy {
        BluetoothDeviceAdapter2(this).apply {
            this.setData(arrayListOf())
            this.setListener(object :BluetoothDeviceAdapter2.OnClickListener{
                override fun onItemClick(pos: Int, device: com.huyuhui.fastble.data.BleDevice?) {
                    device?.let {
                        connect2(it)
                    }
                }
            })
        }
    }

    override fun getLayoutId(): Int = R.layout.activity_bluetooth

    @SuppressLint("MissingPermission")
    override fun initView(savedInstanceState: Bundle?) {
        super.initView(savedInstanceState)
        btnBluetooth = findViewById(R.id.btn_bluetooth)
        btnBluetooth?.setOnClickListener {
            checkBluetooth()
        }
        btnRead = findViewById(R.id.btn_read)
        btnRead?.setOnClickListener {
            mBleDevice?.let {
                com.huyuhui.fastble.BleManager.read(it,uuidService,uuidRead, object :
                    BleReadCallback() {
                        override fun onReadSuccess(
                            bleDevice: com.huyuhui.fastble.data.BleDevice,
                            characteristic: BluetoothGattCharacteristic,
                            data: ByteArray
                        ) {

                            val sb = StringBuilder()
                            data.forEach {
                                sb.append(it)
                            }

                            LogUtils.logGGQ("sb:${sb}")
                        }

                        override fun onReadFailure(
                            bleDevice: com.huyuhui.fastble.data.BleDevice,
                            characteristic: BluetoothGattCharacteristic?,
                            exception: BleException
                        ) {
                            LogUtils.logGGQ("onReadFailure:${exception.description}")
                        }
                })
            }
        }
        rvList = findViewById(R.id.rv_list)
        rvList?.let {
            it.layoutManager = LinearLayoutManager(this)
//            it.adapter = listAdapter
            it.adapter = listAdapter2
        }
    }

//    private val handle: WeakHandler by lazy {
//        WeakHandler(Looper.myLooper(),object : Handler.Callback{
//            @SuppressLint("MissingPermission")
//            override fun handleMessage(message: Message): Boolean {
//                when(message.what) {
//                    100 -> {
//                        mBleDevice?.let {
//                            com.huyuhui.fastble.BleManager.read(it,uuidService,uuidRead, object :
//                                BleReadCallback() {
//                                override fun onReadSuccess(
//                                    bleDevice: com.huyuhui.fastble.data.BleDevice,
//                                    characteristic: BluetoothGattCharacteristic,
//                                    data: ByteArray
//                                ) {
//
//                                    val sb = StringBuilder()
//                                    data.forEach {
//                                        sb.append(it)
//                                    }
//                                    handle.sendEmptyMessageDelayed(100,1000)
//
//                                    val msg = Message()
//                                    msg.what = 200
//                                    msg.obj = data
//
//
//
//                                    handle.sendMessage(msg)
//
//                                    LogUtils.logGGQ("sb:${sb}")
//                                }
//
//                                override fun onReadFailure(
//                                    bleDevice: com.huyuhui.fastble.data.BleDevice,
//                                    characteristic: BluetoothGattCharacteristic?,
//                                    exception: BleException
//                                ) {
//                                    LogUtils.logGGQ("onReadFailure:${exception.description}")
//                                }
//                            })
//                        }
//
//                    }
//                    200 -> {
//
//                    }
//                }
//                return true
//            }
//        })
//    }

    private val handle : Handler = object : Handler(){

        @SuppressLint("MissingPermission")
        override fun handleMessage(msg: Message) {
            super.handleMessage(msg)
            LogUtils.logGGQ("=======${msg.what}")
            when(msg.what) {
                100 -> {
                    mBleDevice?.let { bleDevice ->
                        com.huyuhui.fastble.BleManager.read(bleDevice, uuidService, uuidRead,
                            object : BleReadCallback() {
                                override fun onReadSuccess(
                                    bleDevice: com.huyuhui.fastble.data.BleDevice,
                                    characteristic: BluetoothGattCharacteristic,
                                    data: ByteArray
                                ) {
                                    sendEmptyMessageDelayed(100,1000)
                                    val sb = StringBuilder()
                                    data.forEach {
                                        sb.append(it)
                                    }
                                    val msg = Message()
                                    msg.what = 200
                                    msg.obj = data
                                    msg.arg1 = 290
                                    sendMessage(msg)
                                    LogUtils.logGGQ("sb:${sb}")
                                }

                                override fun onReadFailure(
                                    bleDevice: com.huyuhui.fastble.data.BleDevice,
                                    characteristic: BluetoothGattCharacteristic?,
                                    exception: BleException
                                ) {
                                    LogUtils.logGGQ("onReadFailure:${exception.description}")
                                }

                            })
                    }



                }

                200 -> {

                }
            }
        }
    }

    override fun initData(savedInstanceState: Bundle?) {

    }

    private fun checkBluetooth() {
        if (!packageManager.hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            showToast("设备不支持蓝牙")
            return
        }
        val bluetoothManager: BluetoothManager? = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager?
        bluetoothAdapter = bluetoothManager?.adapter
        if(bluetoothAdapter == null) {
            showToast("设备不支持蓝牙")
            return
        }
        bluetoothLeScanner = bluetoothAdapter?.bluetoothLeScanner
        enabledBluetoothAndLocation()
    }


    private fun enabledBluetoothAndLocation() {
        // 开启蓝牙
        if(!(bluetoothAdapter!!.isEnabled)){
            //不建议强制打开蓝牙，官方建议通过Intent让用户选择打开蓝牙
//            bluetoothAdapter.enable()
            launcherBluetoothResult.launch(Unit)
            return
        }
        // 开启位置服务，
        // 支持获取ble蓝牙扫描结果
        if (!isLocationOpen(applicationContext)) {
            launcherLocationResult.launch(Unit)
            return
        }

        onScanBluetoothDevices()

    }



    private val launcherBluetoothResult = registerForActivityResult(object :
        ActivityResultContract<Unit, Boolean>() {
        override fun createIntent(context: Context, input: Unit): Intent {
            return Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
        }

        override fun parseResult(resultCode: Int, intent: Intent?): Boolean {
            return resultCode == Activity.RESULT_OK
        }
    }) {
        if(it != null && it) {
            showToast("已开启蓝牙")
            enabledBluetoothAndLocation()
        }
    }


    private val launcherLocationResult = registerForActivityResult(object :
        ActivityResultContract<Unit, Boolean>() {
        override fun createIntent(context: Context, input: Unit): Intent {
            return Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
        }

        override fun parseResult(resultCode: Int, intent: Intent?): Boolean {
            return resultCode == Activity.RESULT_OK
        }
    }) {
        if(it != null && it) {
            showToast("已开启位置服务")
            enabledBluetoothAndLocation()
        }
    }

    private fun isLocationOpen(context: Context): Boolean {
        if(Build.VERSION.SDK_INT <  Build.VERSION_CODES.M) return true
        val locationManager: LocationManager? = context.getSystemService(LOCATION_SERVICE) as LocationManager?
        //gps定位
        val isGpsProvider: Boolean = locationManager?.isProviderEnabled(LocationManager.GPS_PROVIDER)?: false
        LogUtils.logGGQ("=isGpsProvider=>${isGpsProvider}")
        //网络定位
        val isNetWorkProvider: Boolean = locationManager?.isProviderEnabled(LocationManager.NETWORK_PROVIDER)?: false
        LogUtils.logGGQ("=isNetWorkProvider=>${isNetWorkProvider}")

        return isGpsProvider || isNetWorkProvider
    }


    private fun onScanBluetoothDevices() {
        if(bluetoothLeScanner == null) {
            showToast("未获取到蓝牙扫描对象")
            return
        }
        LogUtils.logGGQ("开始扫描蓝牙===》")
        listAdapter.clear()

        scan2()
    }

    private fun getScanCallback(showData: Boolean): BleScanCallback.() -> Unit {
        return {
            onScanStart {
                runOnUiThread {
                    showToast("开始扫描")
                    showLoading()
                }
            }
            onLeScan { bleDevice, _ ->
                //可以根据currentScanCount是否已有清空列表数据
                bleDevice.deviceName?.let { _ ->

                }
            }
            onLeScanDuplicateRemoval { bleDevice, _ ->
                bleDevice.deviceName?.let { name ->
                    if (showData) {
                        runOnUiThread {
                            LogUtils.logGGQ("==name===${name}")
                            LogUtils.logGGQ("==address===${name}")
                            listAdapter.addDevice(bleDevice)
                             if(TextUtils.equals("20:23:12:11:01:67",bleDevice.deviceAddress)) {
                                 if(!BleManager.get().isConnected(bleDevice)) {
                                     BleManager.get().connect(bleDevice,connectCallback)
                                 }
                             }
                        }
                    }
                }
            }
            onScanComplete { bleDeviceList, bleDeviceDuplicateRemovalList ->
                //扫描到的数据是所有扫描次数的总和
                bleDeviceList.forEach {
                    it.deviceName?.let { deviceName ->
                        LogUtils.logGGQ("bleDeviceList-> $deviceName, ${it.deviceAddress}")
                    }
                }
                bleDeviceDuplicateRemovalList.forEach {
                    it.deviceName?.let { deviceName ->
                        LogUtils.logGGQ("bleDeviceDuplicateRemovalList-> $deviceName, ${it.deviceAddress}")
                    }
                }
                if (listAdapter.getDataList().isEmpty() && showData) {
                    LogUtils.logGGQ("没有扫描到数据")
                }
                runOnUiThread {
                    dismissLoading()
                }
            }
            onScanFail {
                val msg: String = when (it) {
                    is BleScanFailType.UnSupportBle -> "设备不支持蓝牙"
                    is BleScanFailType.NoBlePermission -> "权限不足，请检查"
                    is BleScanFailType.GPSDisable -> "设备未打开GPS定位"
                    is BleScanFailType.BleDisable -> "蓝牙未打开"
                    is BleScanFailType.AlReadyScanning -> "正在扫描"
                    is BleScanFailType.ScanError -> {
                        "${it.throwable?.message}"
                    }
                    else -> "扫描失败！"
                }
                LogUtils.logGGQ("===listDRData===>>${listAdapter.getDataList().size}")
                runOnUiThread {
                    dismissLoading()
                    showToast(msg)
                }
            }
        }
    }

    private fun scan() {
       if(BleManager.get().isScanning()) {
            BleManager.get().stopScan()
        }
        BleManager.get().disConnectAll()

        GlobalScope.launch {
            BleManager.get().startScan(getScanCallback(true))
        }
    }
    @SuppressLint("MissingPermission")
    private fun scan2() {
        if(com.huyuhui.fastble.BleManager.isScanning()) {
            com.huyuhui.fastble.BleManager.cancelScan()
        }

        com.huyuhui.fastble.BleManager.scan(object : com.huyuhui.fastble.callback.BleScanCallback {
            override fun onLeScan(
                oldDevice: com.huyuhui.fastble.data.BleDevice,
                newDevice: com.huyuhui.fastble.data.BleDevice,
                scannedBefore: Boolean
            ) {
                if(!scannedBefore) {
                    listAdapter2.addDevice(newDevice)
                    if(TextUtils.equals("20:23:12:11:01:67",newDevice.mac)) {
                        connect2(newDevice)
                    }
                }
            }

            override fun onScanFinished(scanResultList: List<com.huyuhui.fastble.data.BleDevice>) {
                dismissLoading()
            }

            override fun onScanStarted(success: Boolean) {
                showLoading()
            }
            override fun onFilter(bleDevice: com.huyuhui.fastble.data.BleDevice): Boolean {
                if(TextUtils.isEmpty(bleDevice.name)) return false
                return true
            }
        })
    }
    var uuidService: String = ""
    var uuidRead: String = ""
    var mBleDevice: com.huyuhui.fastble.data.BleDevice? = null

    @SuppressLint("MissingPermission")
    private fun connect2(bleDevice: com.huyuhui.fastble.data.BleDevice) {
        if (com.huyuhui.fastble.BleManager.isConnected(bleDevice)) {
            com.huyuhui.fastble.BleManager.disconnect(bleDevice)
        }
        com.huyuhui.fastble.BleManager.connect(
            bleDevice,
            object : BleGattCallback() {
                override fun onStartConnect(bleDevice: com.huyuhui.fastble.data.BleDevice) {
                    btnBluetooth?.text = "正在连接"
                }

                override fun onConnectFail(bleDevice: com.huyuhui.fastble.data.BleDevice?, exception: BleException) {
                    btnBluetooth?.text = "连接失败"
                }

                override fun onConnectCancel(bleDevice: com.huyuhui.fastble.data.BleDevice, skip: Boolean) {
                    btnBluetooth?.text = "连接取消"
                }

                override fun onConnectSuccess(
                    bleDevice: com.huyuhui.fastble.data.BleDevice,
                    gatt: BluetoothGatt?,
                    status: Int,
                ) {
                    btnBluetooth?.text = "已连接：${bleDevice.name}"
                    if (com.huyuhui.fastble.BleManager.isScanning()) {
                        com.huyuhui.fastble.BleManager.cancelScan()
                    }

//                    com.huyuhui.fastble.BleManager.read(bleDevice, it.service.uuid.toString(), it.uuid.toString(),

//                    com.huyuhui.fastble.BleManager.getBluetoothGattServices(bleDevice)?.let { list ->
//                        uuidService = list.first().uuid.toString()
//                        list.forEach { gattService ->
//                            LogUtils.logGGQ("uuid:${gattService.uuid}")
//
//                            gattService.characteristics.forEach { gattCharacteristic ->
//                                LogUtils.logGGQ("gattCharacteristic:${gattCharacteristic.uuid}")
//                                LogUtils.logGGQ("properties:${gattCharacteristic.properties}")
//                                LogUtils.logGGQ("properties:${gattCharacteristic.writeType}")
//                            }
//                        }
//                    }
                    val getService: BluetoothGattService? = com.huyuhui.fastble.BleManager.getBluetoothGattServices(bleDevice)?.first()
                    getService?.let {
                        uuidService = it.uuid.toString()
                        uuidRead = it.characteristics.first().uuid.toString()
                    }

                    mBleDevice = bleDevice

                    LogUtils.logGGQ("uuidService:${uuidService}")
                    LogUtils.logGGQ("uuidRead:${uuidRead}")


                    handle.sendEmptyMessageDelayed(100,1000)

                }

                override fun onDisConnected(
                    isActiveDisConnected: Boolean,
                    device: com.huyuhui.fastble.data.BleDevice,
                    gatt: BluetoothGatt?,
                    status: Int,
                ) {
                    btnBluetooth?.text = "已断开"
                }
            })
    }
}